package com.zsj.juc.jmm;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import sun.misc.Unsafe;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author zsj
 * @version 1.0
 * @date 2024/5/8 16:26
 * @description
 */
public class UnsafeTest {
    static AtomicInteger atomicInteger = new AtomicInteger(3); //原子整型

    /*
    思考  给这个变量添加volatile修饰 会有作用吗？
    答案是并不会有作用  volatile底层是保证内存的可见性和有序性 也就是它在一定程度的禁止了指令的重排序
    但是它无法保证数据库的原子性 也就是 它无法保证底层的操作是原子的
     */
    static int number = 3; //非原子整型

    public static void main(String[] args) {

        //在我们自己写的应用程序代码中 我们是不能使用这个类的任何方法的  java.lang.SecurityException: Unsafe
        Unsafe unsafe = Unsafe.getUnsafe();

        for (int i = 0; i < 10; i++) {
            new Thread(new Runner(), i + "").start();
        }

        try {
            TimeUnit.MILLISECONDS.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(atomicInteger.get());//10003
        System.out.println(number);//未知结果 基本上百分之百会有精度丢失
    }

    public static class Runner implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 1000; i++) {
                /*
                  public final native boolean compareAndSetInt(Object o,
                                                 long offset,
                                                 int expected,
                                                 int x);
                 此方法调用了Unsafe中的这个方法  这是一个native的方法
                 简单来说 就是这个指令是底层c++代码执行  由cpu帮我们加了锁
                 由于底层的cpu运行速度很快 就省去了我们自己去再方法或者方法内部添加synchronized
                 而且synchronized的属于一个重量级锁 这个方法还可以帮我们省去一定的性能开销
                 */
                atomicInteger.incrementAndGet();
                number++;
            }
        }
    }
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class User {
    private String name;
    private int age;
}

